/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rukopisyimport.sourceData;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.DocumentException;

/**
 *
 * @author Martin Rehanek (rehan@mzk.cz)
 */
public class SourceDocumentsManager {

    private static final String TEI_FILE_SUFFIX = ".tei.xml";
    private static final String MARC_FILE_SUFFIX = ".marc21.xml";
    private final File documentDir;
    private final Set<File> teiFiles;
    private final Set<File> digitizedTeiFiles;
    //TODO: zahrnout validaci! tei a marc
    //NETREBA VALIDOVAT, pokud budu tahat ze oai a bude se validovat tam
    private final Set<File> marcFiles;
    private final Properties properties;
    private Marc21Downloader marc21Downloader = null;

    public SourceDocumentsManager(File documentDir, Properties properties) {
        this.documentDir = documentDir;
        this.properties = properties;
        teiFiles = findFiles(documentDir, TEI_FILE_SUFFIX);
        marcFiles = findFiles(documentDir, MARC_FILE_SUFFIX);
        digitizedTeiFiles = selectDigitized(teiFiles);
    }

    private Set<File> findFiles(File dir, final String suffix) {
        //System.err.println("dir: " + dir.getAbsolutePath());
        File[] fileArray = dir.listFiles(new FilenameFilter() {

            public boolean accept(File dir, String name) {
                return name.endsWith(suffix);
            }
        });
        return arrayToSet(fileArray);
    }

    private Set<File> arrayToSet(File[] files) {

        List<File> fileList = Arrays.asList(files);
        return new HashSet(fileList);
    }

    private Set<File> selectDigitized(Set<File> teiFiles) {
        Set<File> result = new HashSet<File>();
        for (File file : teiFiles) {
            try {
                TeiDocument tei = new TeiDocument(file);
                if (tei.isDigitalized()) {
                    result.add(file);
                }
            } catch (FileNotFoundException ex) {
                Logger.getLogger(SourceDocumentsManager.class.getName()).log(Level.SEVERE, null, ex);
            } catch (DocumentException ex) {
                Logger.getLogger(SourceDocumentsManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return result;
    }

    public void downloadMarcRecordsForDigitalizedTeis(boolean rewriteExisting) {
        for (File teiFile : digitizedTeiFiles) {
            try {
                TeiDocument tei = new TeiDocument(teiFile);
                String signature = tei.findSignature();
                File marcFile = marcFileFromTeiFile(teiFile);
                if (!marcFile.exists() || rewriteExisting) {
                    System.err.println("downloading marc record for " + teiFile.getAbsolutePath());
                    getMarc21Downloader().createMarcRecord(signature, marcFile);
                }
            } catch (FileNotFoundException ex) {
                Logger.getLogger(SourceDocumentsManager.class.getName()).log(Level.SEVERE, null, ex);
            } catch (DocumentException ex) {
                Logger.getLogger(SourceDocumentsManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private Marc21Downloader getMarc21Downloader() {
        if (marc21Downloader == null) {
            loadMarcDownloader();
        }
        return marc21Downloader;
    }

    private void loadMarcDownloader() {
        this.marc21Downloader = new Marc21Downloader(properties);
    }

    public void printStatistics(boolean detailed) {
        System.out.println("tei documents: " + teiFiles.size());
        System.out.println("not digitalized: " + (teiFiles.size() - digitizedTeiFiles.size()));
        if (detailed) {
            for (File file : teiFiles) {
                if (!digitizedTeiFiles.contains(file)) {
                    System.out.println(file.getAbsolutePath());
                }
            }
        }

        System.out.println("digitalized tei:" + digitizedTeiFiles.size());
        if (detailed) {
            for (File file : digitizedTeiFiles) {
                System.out.println(file.getAbsolutePath());
            }
        }
        Set<String> ready = signaturesOfReady();
        System.out.println("tei and marc:" + ready.size());
        if (detailed) {
            for (String signature : ready) {
                System.out.println(signature);
            }
        }

        Set<String> digitizedWithoutMarc = signaturesOfDigitizedWithoutMarc();
        System.out.println("digitized without marc:" + digitizedWithoutMarc.size());
        if (detailed) {
            if (detailed) {
                for (String signature : digitizedWithoutMarc) {
                    System.out.println(signature);
                }
            }
        }
    }

    /**
     *
     * @return signatures of these object, that have digitized tei document and also marc21 document present
     */
    public Set<String> signaturesOfReady() {
        Set<String> result = new HashSet<String>();
        for (String signature : signaturesOfDigitized()) {
            File marcFile = marcFileFromSignature(signature);
            if (marcFiles.contains(marcFile)) {
                result.add(signature);
            }
        }
        return result;
    }

    public Set<String> signaturesOfDigitized() {
        Set<String> result = new HashSet<String>();
        for (File teiFile : digitizedTeiFiles) {
            String signature = signatureFromTeiFileName(teiFile);
            result.add(signature);
        }
        return result;
    }

    public Set<File> getDigitizedFiles(){
        return digitizedTeiFiles;
    }

    public Set<String> signaturesOfDigitizedWithoutMarc() {
        Set<String> result = new HashSet<String>();
        for (String signature : signaturesOfDigitized()) {
            File marcFile = marcFileFromSignature(signature);
            if (!marcFiles.contains(marcFile)) {
                result.add(signature);
            }
        }
        return result;
    }

    public File marcFileFromTeiFile(File teiFile) {
        String signature = signatureFromTeiFileName(teiFile);
        return marcFileFromSignature(signature);
    }

    private String signatureFromTeiFileName(File teiFile) {
        String filename = teiFile.getName();
        String sysno = filename.substring(0, (filename.length() - TEI_FILE_SUFFIX.length()));
        return sysno;
    }

    private File marcFileFromSignature(String signature) {
        StringBuilder result = new StringBuilder();
        result.append(documentDir.getAbsoluteFile());
        result.append(File.separatorChar);
        result.append(signature);
        result.append(MARC_FILE_SUFFIX);
        return new File(result.toString());
    }
}
